package cp.remote.network;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import android.util.Log;

public abstract class Worker extends Network {

    private volatile boolean running = false;
    private volatile boolean lastcommandok = false; 
    private Connection connection;
    private Thread tp = null;
    private Lock clock = new ReentrantLock();
    private Condition message = clock.newCondition();
    private BlockingQueue<String> commands = new LinkedBlockingQueue<String>();
    private String name ="";
    
    protected Worker(String name, String ip, int port) {
        super(name);
        this.name = name;
        connection = (new Connection(ip, port));
        Log.i(name, "Created");
    }   
    
    public boolean start() {
        tp = new Thread(this);
        running = true;
        tp.start();
        Log.i(name, "Startet");
        return true;
    }

    public void stop() {
        clock.lock();
        running = false;
        commands.clear();
        message.signal();
        Log.i(name, "Stoped");
        clock.unlock();
    }

    public void send(String cmd) {
        clock.lock();
        commands.add(cmd);
        message.signal();
        clock.unlock();
    }
    
    public synchronized boolean isRunning() {
        return running;
    }

    public synchronized boolean isConnected(){ return connection.isConnected();}
    
    public synchronized boolean isLastCommandOk() {
        return lastcommandok;
    }   
    
    public void run() {
        try {

            while (isRunning()) {
                if (connection.isConnected()) {
                    clock.lock();
                    if (commands.size() == 0) {
                        Log.d(name, "Wait for command");
                        message.await();
                    }
                    clock.unlock();
                    for (String s : commands) {
                        lastcommandok = false;
                        connection.sendCmd(s);
                        Log.i(name, "send: " + s);
                        
                        if (!connection.checkCmd())
                            error("Last Sendet Command not ok");
                        else{
                            lastcommandok = true;
                            if(isError()) resetError(); // Reset error for wrong command
                        }
                        commands.remove(s);
                    }
                } else {
                    connection.connect();
                }
            }

        } catch (UnknownHostException e) {
            error(e.getMessage());
        } catch (IOException e) {
            error(e.getMessage());
        } catch (InterruptedException e) {
            error(e.getMessage());
        } finally {
            try {
                connection.disconnect();
            } catch (IOException e) {
            }
            Log.i(name, "Shutdown");
        }
    }
}
